//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Diagnostics;

namespace OpenLS.Spreadsheet.Expressions
{

    internal class DynamicCellReference : CellReference
    {
        private readonly Cell _actualCell;
        private readonly bool _lockColumn;
        private readonly bool _lockRow;
        private CellRelativeAddress _diff;

        public DynamicCellReference(AnchoredRowReference row, AnchoredColumnReference column)
        {
            _lockRow = row.IsLocked;
            _lockColumn = column.IsLocked;
            _actualCell = row.Worksheet[row.Anchor.Index, column.Anchor.Index];
            _diff = new CellRelativeAddress(new CellAddress(row.Anchor.Index, column.Anchor.Index),
                                            _actualCell.Address);
            //_diff = _actualCell.Address - new CellAddress(row.Anchor.Index, column.Anchor.Index);
        }

        internal override RowReference Row
        {
            get { return new AnchoredRowReference(Worksheet.Rows[_actualCell.Row.Index + _diff.Row], _lockRow); }
        }

        internal override ColumnReference Column
        {
            get { return new AnchoredColumnReference(Worksheet.Columns[_actualCell.Column.Index + _diff.Column], _lockColumn); }
        }

        //  readonly RowReference Row;
        //\\readonly ColumnReference Column;

        public override Worksheet Worksheet
        {
            get { return _actualCell.Worksheet; }
        }

        public override Cell Cell
        {
            get
            {
                return _actualCell;
            }
        }

        internal override CellReference ToggleLock()
        {
            AnchoredRowReference rr = (AnchoredRowReference) this.Row;
            AnchoredColumnReference cr = (AnchoredColumnReference) Column;
            if (rr.IsLocked)
            {
                if (cr.IsLocked)
                {
                    cr = new AnchoredColumnReference(cr.Anchor, false);
                }
                else
                {
                    rr = new AnchoredRowReference(rr.Anchor, false);
                    cr = new AnchoredColumnReference(cr.Anchor, true);
                }
            }
            else
            {
                if (cr.IsLocked)
                    cr = new AnchoredColumnReference(cr.Anchor, false);
                else
                {
                    cr = new AnchoredColumnReference(cr.Anchor, true);
                    rr = new AnchoredRowReference(rr.Anchor, true);
                }
            }
            return new DynamicCellReference(rr, cr);
        }

        internal override CellReference Projected(Worksheet targetWorksheet)
        {
            return
                new DynamicCellReference(
                    new AnchoredRowReference(targetWorksheet.Rows[this.Cell.Row.Index], this._lockRow),
                    new AnchoredColumnReference(targetWorksheet.Columns[this.Cell.Column.Index], _lockColumn));
        }

        public override CellReference Offset(CellRelativeAddress a)
        {
            var c = (AnchoredColumnReference) Column.Offset(a);
            var r = (AnchoredRowReference) Row.Offset(a);
            //\\if (c == Column && r == Row)
            //\\return this;
            return new DynamicCellReference(r, c);
        }
    }
}